package chapter02

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

// 建立标签，实现表单数据和其绑定，，这个是json绑定的方式`json:"id"`
type UserInfo struct {
	Id   int    `form:"id"`
	Name string `form:"name"`
	Age  int    `form:"age"`
	Addr string `form:"addr"`
}

func User(ctx *gin.Context) {
	name := "vick"
	ctx.HTML(200, "user/user.html", name)
}

// 结构体渲染
func UserInfoStruct(ctx *gin.Context) {
	user_info := UserInfo{Id: 1, Name: "vick", Age: 18, Addr: "sz"}
	ctx.HTML(http.StatusOK, "chapter02/user_info.html", user_info)
}

// 数组渲染
func ArrController(ctx *gin.Context) {
	arr := []int{1, 2, 3, 4}
	ctx.HTML(http.StatusOK, "chapter02/arr.html", arr)
}

// 结构体数组
func ArrStruct(ctx *gin.Context) {
	arr_struct := []UserInfo{}
	arr_struct = append(arr_struct, UserInfo{Id: 1, Name: "hell", Age: 18, Addr: "szw"})
	arr_struct = append(arr_struct, UserInfo{Id: 2, Name: "hell", Age: 18, Addr: "szw"})
	arr_struct = append(arr_struct, UserInfo{Id: 3, Name: "hell", Age: 18, Addr: "szw"})
	ctx.HTML(http.StatusOK, "chapter02/arr_struct.html", arr_struct)
}

// map
func MapController(ctx *gin.Context) {

	map_data := map[string]string{"name": "vick", "addr": "深圳"}
	map_data2 := map[string]string{"addr": "北京"}

	map_data_end := map[string]interface{}{"map_data": map_data, "map_data2": map_data2}
	ctx.HTML(http.StatusOK, "chapter02/map.html", map_data_end)
}

// map+结构体
func MapStruct(ctx *gin.Context) {

	map_struct := map[string]UserInfo{}
	map_struct["p1"] = UserInfo{Id: 1, Name: "halen", Age: 12, Addr: "sz"}

	ctx.HTML(http.StatusOK, "chapter02/map_struct.html", map_struct)
}

// 路径直接加上参数值
func Param1(ctx *gin.Context) {
	// 第一种方式，获取路由上的参数值
	id := ctx.Param("id")
	ctx.String(http.StatusOK, "hello, %s", id)
}

func Param2(ctx *gin.Context) {
	// 第一种方式，获取路由上的参数值
	id := ctx.Param("id")
	ctx.String(http.StatusOK, "hello, %s", id)
}

// http://localhost:9000/query?id=123
// 第二种方式
func GetQueryData(ctx *gin.Context) {
	// id := ctx.Query("id") // 根据参数名获取值
	name := ctx.DefaultQuery("id", "hello") // 根据参数名获取，如果没有，则使用默认值
	ctx.String(http.StatusOK, "hello, %s", name)
}

// 获取数组参数
// http://localhost:9000/query_arr?id=12,32,21,65
func GetQueryArrData(ctx *gin.Context) {
	name := ctx.QueryArray("id") // 获取数组参数
	ctx.String(http.StatusOK, "hello, %s", name)
}

// 获取map的参数类型
func GetMapData(ctx *gin.Context) {
	name := ctx.QueryMap("user") // 获取map参数
	ctx.String(http.StatusOK, "hello, %s", name)
}

// post请求,,用户添加页面
func ToUserAdd(ctx *gin.Context) {
	ctx.HTML(http.StatusOK, "chapter02/user_add.html", nil)
}

// 添加用户
func DoUserAdd(ctx *gin.Context) {
	username := ctx.PostForm("username")
	password := ctx.PostForm("password")
	fmt.Println(username, ",", password)
	ctx.String(http.StatusOK, "添加成功")
}

// DefaultPostForm用法
// post请求,,用户添加页面
func ToUserAdd2(ctx *gin.Context) {
	ctx.HTML(http.StatusOK, "chapter02/user_add2.html", nil)
}

// 添加用户
func DoUserAdd2(ctx *gin.Context) {
	username := ctx.PostForm("username")
	password := ctx.PostForm("password")
	age := ctx.DefaultPostForm("age", "18") // 当没有传递的时候，默认使用18
	loves := ctx.PostFormArray("love")      // 获取数组
	user := ctx.PostFormMap("user")         // 获取map类型

	fmt.Println(username, ",", password, ",", age, ", ", loves, ", ", user)
	ctx.String(http.StatusOK, "添加成功")
}

// ajax用法
// post请求,,用户添加页面
func ToUserAdd3(ctx *gin.Context) {
	ctx.HTML(http.StatusOK, "chapter02/user_add3.html", nil)
}

// 添加用户
// ajax把form表单的数据发给DoUserAdd
func DoUserAdd3(ctx *gin.Context) {
	username := ctx.PostForm("username")
	password := ctx.PostForm("password")
	age := ctx.PostForm("age")

	fmt.Println(username, ",", password, ",", age)

	// 成功之后返回，必须返回json类型
	// map_data := map[string]interface{}{
	// 	"code": 200,
	// 	"msg":  "成功",
	// }
	// ctx.JSON(http.StatusOK, map_data)
	// 可以使用gin自带的类型返回
	ctx.JSON(http.StatusOK, gin.H{"code": 20, "msg": "成功"})
}

// 参数绑定
func ToUserAdd4(ctx *gin.Context) {
	ctx.HTML(http.StatusOK, "chapter02/user_add4.html", nil)
}

func DoUserAdd4(ctx *gin.Context) {
	var user_info UserInfo
	// 绑定
	err := ctx.ShouldBind(&user_info)
	fmt.Println(err)
	fmt.Println(user_info)

	ctx.String(http.StatusOK, "绑定成功")
}
